package com.example.demo.core.util;

import com.google.common.primitives.Bytes;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.sip.RequestEvent;
import javax.sip.message.Request;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class XmlUtil {


    public static Element getRootElement(RequestEvent evt, String charset) throws DocumentException {

        if (charset == null) {
            charset = "gb2312";
        }
        Request request = evt.getRequest();
        SAXReader reader = new SAXReader();
        reader.setEncoding(charset);
        // 对海康出现的未转义字符做处理。
        String[] destStrArray = new String[]{"&lt;","&gt;","&amp;","&apos;","&quot;"};
        // 或许可扩展兼容其他字符
        char despChar = '&';
        byte destBye = (byte) despChar;
        List<Byte> result = new ArrayList<>();
        byte[] rawContent = request.getRawContent();
        if (rawContent == null) {
            return null;
        }
        for (int i = 0; i < rawContent.length; i++) {
            if (rawContent[i] == destBye) {
                boolean resul = false;
                for (String destStr : destStrArray) {
                    if (i + destStr.length() <= rawContent.length) {
                        byte[] bytes = Arrays.copyOfRange(rawContent, i, i + destStr.length());
                        resul = resul || (Arrays.equals(bytes,destStr.getBytes()));
                    }
                }
                if (resul) {
                    result.add(rawContent[i]);
                }
            }else {
                result.add(rawContent[i]);
            }
        }
        byte[] bytesResult = Bytes.toArray(result);

        Document xml;
        try {
            xml = reader.read(new ByteArrayInputStream(bytesResult));
        }catch (DocumentException e) {
            log.warn("[xml解析异常]： 原文如下： \r\n{}", new String(bytesResult));
            log.warn("[xml解析异常]： 原文如下： 尝试兼容性处理");
            String[] xmlLineArray = new String(bytesResult).split("\\r?\\n");

            // 兼容海康的address字段带有<破换xml结构导致无法解析xml的问题
            StringBuilder stringBuilder = new StringBuilder();
            for (String s : xmlLineArray) {
                if (s.startsWith("<Address")) {
                    continue;
                }
                stringBuilder.append(s);
            }
            xml = reader.read(new ByteArrayInputStream(stringBuilder.toString().getBytes()));
        }
        return xml.getRootElement();
    }

}
